const Router = require('koa-router')
const uuid = require('uuid')
const { check, catchError, generateOk } = require('../../lib/check')
const { writeToken, searchToken, removeToken, editToken, clearToken, searchTokenByAccount } = require('../../model/token')
const { setAccount, searchAccount, editAccount, getAllAccounts, searchAccountById } = require('../../model/accounts')
const { reFreshToken } = require('./tool')
const { searchPassword, editPassword, setPassword } = require('../../model/password')
let account = new Router()

account.post('/login', async (ctx) => {
  try {
    let data = ctx.request.body
    clearToken()
    check(!!data.account, 'Account_Is_Empty')
    check(!!data.password, 'Pwd_Is_Empty')
    let accountInfo = searchPassword(data.account)
    check((accountInfo && accountInfo.status !== 0), 'Not_Auth')
    check(accountInfo.password === data.password, 'Wrong_Pwd')
    const findAccount = searchAccount(data.account)
    check(!findAccount.froozen, 'Account_Has_Been_Froozen')
    let token = uuid.v4()
    const time = (new Date()).getTime()
    const findToken = searchTokenByAccount(data.account)
    if (!!findToken) {
      editToken({ account: findToken.account, token: token, time: time + 600000 })
    } else {
      // 记录token
      writeToken({ account: data.account, token: token, time: time + 600000 })
    }
    // 写入头部
    ctx.cookies.set('token', token, {
      httpOnly: true, // 是否只用于http请求中获取
      overwrite: false, // 是否允许重写
    })
    ctx.body = generateOk({ token })
  } catch (err) {
    catchError(err, ctx)
  }
})

account.post('/register', async (ctx) => {
  try {
    let data = ctx.request.body
    let allAccount = getAllAccounts()
    let valueArr = Object.values(data).filter((item) => !!item)
    let time = new Date()
    check(valueArr.length >= 4, "Params_Lost")
    let searchedAccount = searchAccount(data.telephone)
    check(!searchedAccount, 'Account_Has_Been_Exist')
    check(!!(data.setPassword === data.confirmPassword), 'Deferent_Password')
    check(!!data.setPassword.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,16}$/), 'Simple_Password')
    let newAccount = {
      focus: [],
      nickname: data.nickname || "用户" + data.telephone,
      account: data.telephone,
      id: allAccount.length.toString().padStart(6, '0'),
      slogan: '',
      city: '',
      sex: '',
      avatar: '',
      age: "0",
      role: 'normal',
      inWhiteList: false,
      froozen: false,
      score: 0,
      vip: false,
      status: 1,
      createAt: (time.getTime()).toString()
    }
    setAccount(newAccount)
    setPassword({ account: data.account, password: data.setPassword, status: 1 })
    ctx.body = generateOk({
      info: {
        nickname: newAccount.nickname,
        account: newAccount.account,
      },
    })
  } catch (e) {
    catchError(e, ctx)
  }
})

account.post('/changeAvatar', async (ctx) => {
  try {
    const data = ctx.request.body
    check(!!data.account, 'Params_Lost')
    check(!!data.avatar, 'Params_Lost')
    const findAccount = searchAccount(data.account)
    check(findAccount, 'Not_Auth')
    editAccount({ ...findAccount, avatar: data.avatar })
    ctx.body = generateOk({ ...findAccount, avatar: data.avatar })
  } catch (e) {
    catchError(e, ctx)
  }
})

account.post('/getUserInfo', async (ctx) => {
  try {
    let account = ctx.request.body
    let token = ctx.cookies.get("token")
    check(!!account.account, 'Params_Lost')
    const findToken = searchTokenByAccount(account.account)
    if (!!findToken) {
      check(token === findToken.token, 'User_Login_Outdate')
    }
    const findAccount = searchAccount(account.account)
    check(findAccount, 'Not_Auth')
    reFreshToken(ctx)
    ctx.body = generateOk(findAccount)
  } catch (err) {
    catchError(err, ctx)
  }
})

account.post('/getUser', async (ctx) => {
  try {
    let account = ctx.request.body
    check(!!account.userId, 'Params_Lost')
    const findAccount = searchAccountById(account.userId)
    check(findAccount, 'Not_Auth')
    // reFreshToken(ctx)
    ctx.body = generateOk(findAccount)
  } catch (err) {
    catchError(err, ctx)
  }
})

account.post('/getFocusUser', async (ctx) => {
  try {
    let data = ctx.request.body
    check(!!data.focus, 'Params_Lost')
    check(data.focus.length !== 0, "No_Focus")
    const focuseInfo = data.focus.map((id) => searchAccountById(id))
    const result = focuseInfo.filter(user => (user.status === 1 && !user.froozen))
    ctx.body = generateOk(result)
  } catch (err) {
    catchError(err, ctx)
  }
})
account.post('/resetPassword', async (ctx) => {
  try {
    const data = ctx.request.body
    check(!!data.account, 'Params_Lost')
    const findAccount = searchPassword(data.account)
    check(findAccount, 'Not_Auth')
    check(!!(data.newPassword && data.newConfirmPassword), 'Params_Lost')
    check(!!(data.newPassword === data.newConfirmPassword), 'Deferent_Password')
    check(!!data.newPassword.match(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,16}$/), 'Simple_Password')
    const newAccount = { ...findAccount, password: data.newPassword }
    editPassword(newAccount)
    ctx.body = generateOk({ accountInfo: newAccount })
  } catch (e) {
    catchError(e, ctx)
  }
})

account.post('/change', async (ctx) => {
  try {
    const data = ctx.request.body
    check(!!data.account, 'Params_Lost')
    const findAccount = searchAccount(data.account)
    check(findAccount, 'Not_Auth')
    const newAccount = { ...findAccount, ...data }
    editAccount(newAccount)
    reFreshToken(ctx)
    ctx.body = generateOk({ accountInfo: newAccount })
  } catch (e) {
    catchError(e, ctx)
  }
})

account.post("/focus", async (ctx) => {
  try {
    const data = ctx.request.body
    let result
    check(data.userId, 'Params_Lost')
    check(data.targetId, 'Params_Lost')
    const findAccount = searchAccountById(data.userId)
    check(findAccount, 'Not_Auth')
    console.log(findAccount)
    if (findAccount.focus.findIndex(data.targetId) !== -1) {
      result = findAccount.focus.filter((id) => id !== data.targetId)
    } else {
      result = findAccount.focus.push(data.targetId)
    }
    editAccount({ ...findAccount, focus: result })
    ctx.body = generateOk({ ...findAccount, focus: result })
  } catch (e) {
    catchError(e, ctx)
  }
})

account.post('/logout', async (ctx) => {
  try {
    // 解析header中的token
    console.log('登出')
    let token = ctx.cookies.get("token")
    check(!!token, 'User_Not_Login')
    check(!!searchToken(token), 'User_Login_Outdate')
    removeToken(token)
    ctx.body = generateOk()
  } catch (err) {
    catchError(err, ctx)
  }
})

module.exports = account